package com.lian.hope.service.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lian.hope.enums.RoleType;
import com.lian.hope.mapper.*;
import com.lian.hope.model.dto.UserDTO;
import com.lian.hope.model.dto.UsersAuthDTO;
import com.lian.hope.model.po.Permission;
import com.lian.hope.model.po.SignInRecords;
import com.lian.hope.model.po.Users;
import com.lian.hope.model.vo.*;
import com.lian.hope.properties.WeChatProperties;
import com.lian.hope.service.UsersService;
import com.lian.hope.utils.HttpClientUtil;
import com.lian.hope.utils.JwtUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;

@RequiredArgsConstructor
@Service
@Slf4j
public class UserServiceImpl implements UsersService {
    private final WeChatProperties weChatProperties;
    private final ProjectsDonationsMapper projectsDonationsMapper;
    private final UsersMapper usersMapper;
    private final ProjectsMapper projectsMapper;
    private final VolunteerActivitiesMapper volunteerActivitiesMapper;
    private final VolunteerRegisterMapper volunteerRegisterMapper;
    private final SignInRecordsMapper signInRecordsMapper;
    private final String WECHAT_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";

    @Override
    @Transactional
    public String authWechatLogin(UsersAuthDTO usersAuthDTO) {
        // 获取 openid
        String openId = getOpenId(usersAuthDTO.getCode());
        // 查询用户是否已存在
        UserRoleVO userRoleVO = usersMapper.getUserByOpenId(openId);
        HashMap<String, Object> claims = new HashMap<>();
        if (userRoleVO == null) {
            // 如果用户不存在，则创建用户
            Users userBuild = Users.builder().openId(openId).nickname(usersAuthDTO.getNickname()).avatarUrl(
                usersAuthDTO.getAvatarUrl()).createTime(LocalDateTime.now()).role(RoleType.ADMINISTRATOR.getRole()).build();
            usersMapper.insertUser(userBuild);
            // 新增用户和角色关系
            usersMapper.insertUserRole(userBuild.getId(), RoleType.USER.getCode());
            // 生成token
            claims.put("nickname", userBuild.getNickname());
            // 给予普通用户的角色
            claims.put("roleId", RoleType.USER.getCode());
            claims.put("userId", userBuild.getId());

            return JwtUtil.genToken(claims);

        }
        // 用户已存在
        claims.put("nickname", userRoleVO.getNickname());
        // 给予普通用户的角色
        claims.put("roleId", RoleType.USER.getCode());
        claims.put("userId", userRoleVO.getId());

        return JwtUtil.genToken(claims);
    }

    /**
     * 根据用户id更新用户信息
     *
     * @param userDTO
     * @param userId
     * @return
     */
    @Override
    public void updateUsersById(UserDTO userDTO, Long userId) {
        Users users = Users.builder().nickname(userDTO.getNickname()).phoneNumber(userDTO.getPhoneNumber()).address(
            userDTO.getAddress()).avatarUrl(userDTO.getAvatarUrl()).id(userId).build();

        log.info("user:{}", users);

        usersMapper.updateUsersById(users);
    }

    /**
     * 获取用户所有捐款的项目
     *
     * @param userId
     * @return
     */
    @Override
    public List<ProjectsVO> listDonationsProjectsByUserId(Long userId) {
        List<Long> projectIds = projectsDonationsMapper.listDonationsProjectIdsByUserId(userId);
        if (projectIds.isEmpty())
            return List.of();

        return projectsMapper.listProjectsByIds(projectIds);
    }

    /**
     * 根据用户id获取用户所有报名活动
     *
     * @param userId
     * @return
     */
    @Override
    public List<VolunteerActivitiesVO> listRegisterActivitiesByUserId(Long userId) {
        List<Long> volunteerIds = volunteerRegisterMapper.listRegisterActivitiesIdsByUserId(userId);
        if (volunteerIds.isEmpty())
            return List.of();
        List<VolunteerActivitiesVO> volunteerActivitiesVOS = volunteerActivitiesMapper.listVolunteerActivitiesByIds(
            volunteerIds);

        return volunteerActivitiesVOS;
    }

    @Override
    public UsersVO getUserInfoById(Long userId) {
        log.info("需要获取的用户id：{}", userId);

        Users user = usersMapper.getUserById(userId);
        return UsersVO.builder().nickname(user.getNickname()).phoneNumber(user.getPhoneNumber()).avatarUrl(
                user.getAvatarUrl()).phoneNumber(user.getPhoneNumber()).points(user.getPoints()).address(user.getAddress())
            .role(user.getRole()).build();

    }

    /**
     * 登录管理员账号
     *
     * @return
     */
    @Override
    public String loginAdminUser() {

        UserRoleVO admin = usersMapper.getUserByOpenId("admin");
        //        if (admin == null) {
        //            Users userBuild = Users.builder().openId("admin").nickname("admin").avatarUrl(
        //                "https://hope-mp.oss-cn-guangzhou.aliyuncs.com/20240916095732.jpg").build();
        //
        //// 添加用户
        //           Users user =  usersMapper.insertUser(userBuild);
        //
        //           // 新增用户和角色关系
        //            usersMapper.insertUserRole(user.getId(), RoleType.ADMINISTRATOR);
        //
        //        }

        HashMap<String, Object> claims = new HashMap<>();
        claims.put("nickname", admin.getNickname());
        // 给予用户管理员的权限
        claims.put("roleId", RoleType.ADMINISTRATOR.getCode());
        claims.put("userId", admin.getId());

        return JwtUtil.genToken(claims);

    }

    /**
     * 更新用户积分
     *
     * @param points
     * @param userId
     */
    @Override
    public Boolean updateUserPointsById(Integer points, Long userId) {

        // 查询用户是否已签到
        SignInRecords signInRecords = signInRecordsMapper.findByUserIdAndToday(userId);

        if (signInRecords != null)
            return false;

        SignInRecords sign = SignInRecords.builder().userId(userId).signInDate(LocalDateTime.now()).build();
        signInRecordsMapper.insertSignInRecord(sign);

        usersMapper.updateUserPointsById(points, userId);
        return true;
    }

    /**
     * 根据角色id获取用户对应的权限列表
     *
     * @param roleId
     * @return
     */
    @Override
    public List<Permission> queryPermissionByRoleId(Integer roleId) {
        return usersMapper.queryPermissionByRoleId(roleId);
    }

    @Override
    @Transactional
    public List<OperateVO> getUserOperateByRole(Long userId) {
        Integer roleId = usersMapper.getUserRoleByUserId(userId);
        log.info("roleId:{}", roleId);
        // 根据角色id获取用户对应的操作列表
        List<Integer> operateIds = usersMapper.getUserOperateByRole(roleId);
        log.info("operateIds:{}", operateIds);
        return usersMapper.getOperateByIds(operateIds);
    }

    @Override
    @Transactional
    public String smsLogin(String phoneNumber, String wxCode) {
        String openId = getOpenId(wxCode);
        UserRoleVO userRoleVO = usersMapper.getUserByOpenId(openId);
        HashMap<String, Object> clamis = new HashMap<>();
        if (userRoleVO != null) {
            clamis.put("nickname", userRoleVO.getNickname());
            clamis.put("roleId", RoleType.USER.getCode());
            clamis.put("userId", userRoleVO.getId());
            String token = JwtUtil.genToken(clamis);
            return token;
        }

        // 查询该账号是否已注册
        Users user = usersMapper.getUserByPhoneNumber(phoneNumber);
        if (user == null) {
            Users userBuild = Users.builder().role("user").nickname(phoneNumber).openId(openId).phoneNumber(phoneNumber)
                .avatarUrl(
                    "https://thirdwx.qlogo" + ".cn/mmopen/vi_32" +
                    "/POgEwh4mIHO4nibH0KlMECNjjGxQUq24ZEaGT4poC6icRiccVGKSyXwibcPq4BWmiaIGuG1icwxaQX6grC9VemZoJ8rg/132")
                .createTime(LocalDateTime.now()).build();
            log.info("user:{}", userBuild);
            usersMapper.insertUser(userBuild);
            usersMapper.insertUserRole(userBuild.getId(), RoleType.USER.getCode());

            clamis.put("nickname", userBuild.getNickname());
            clamis.put("roleId", RoleType.USER.getCode());
            clamis.put("userId", userBuild.getId());
            String token = JwtUtil.genToken(clamis);

            return token;
        }
        clamis.put("nickname", user.getNickname());
        clamis.put("roleId", RoleType.USER.getCode());
        clamis.put("userId", user.getId());

        String token = JwtUtil.genToken(clamis);

        return token;
    }

    @Override
    public Boolean getUserByPhoneNumber(String phoneNumber) {
        Users user = usersMapper.getUserByPhoneNumber(phoneNumber);

        return user != null;
    }

    /**
     * 调用微信接口服务,使用code获取当前用户的openId
     *
     * @param code
     * @return
     */
    public String getOpenId(String code) {
        // 封装请求参数
        HashMap<String, String> map = new HashMap<>();
        map.put("appid", weChatProperties.getAppId());
        map.put("secret", weChatProperties.getSecret());
        map.put("js_code", code);
        map.put("grant_type", "authorization_code");
        // 使用封装好的 HttpClientUtil 从微信后台请求
        String json = HttpClientUtil.doGet(WECHAT_LOGIN_URL, map);
        // 将获取过来的数据解析出来
        JSONObject jsonObject = JSON.parseObject(json);
        // 获取openId
        log.info("jsonObject:{}", jsonObject);
        return jsonObject.getString("openid");
    }
}
